package com.example.cc.client.service;

import cn.hutool.core.map.MapUtil;
import com.example.cc.client.manager.CacheManager;
import com.example.cc.client.manager.GenericCacheManager;
import com.example.cc.client.properties.ConfigCenterProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
@SuppressWarnings("all")
public class ReigsterSyncService {

    @Resource
    private GenericCacheManager<String, Object> cacheManager;
    private final ConfigCenterProperties configCenterProperties;
    private final RestTemplate restTemplate;
    private final ClientRegisterService clientRegisterService;

    /**
     * 同步配置并注册自身到配置中心
     */
    public void syncAndRegister() {
        try {
            // 注册自身到配置中心
            register2ConfigCenter();
            // 同步配置，这种方式达不到效果
            // syncConfiguration();
        } catch (Exception e) {
            log.error("Failed to sync and register with the config center: {}", e.getMessage());
        }
    }

    /**
     * 向配置中心注册自身
     */
    private void register2ConfigCenter() {
        clientRegisterService.doRegister();
    }

    private void syncConfiguration() {
        String serverUrl = configCenterProperties.getServerUrl();
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(serverUrl)
                .path("/api/config/all");
        ResponseEntity<Map<String, String>> response = restTemplate.exchange(
                builder.toUriString(),
                HttpMethod.GET,
                new HttpEntity<>(createHeaders()),
                new ParameterizedTypeReference<Map<String, String>>() {
                }
        );
        if (response.getStatusCode().is2xxSuccessful()) {
            Map<String, String> configs = response.getBody();
            if (MapUtil.isNotEmpty(configs)) {
                updateLocalCache(configs);
            }
        } else {
            throw new RuntimeException("Failed to fetch configurations from config center");
        }
    }

    /**
     * 更新本地缓存中的配置
     */
    private void updateLocalCache(Map<String, String> configs) {
        configs.forEach(cacheManager::update);
    }


    /**
     * 创建HTTP请求头。
     */
    private HttpHeaders createHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        return headers;
    }
}
